<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.4"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Flow: flow::net_flow::Socket_buffer Class Reference</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr id="projectrow">
  <td id="projectalign">
   <div id="projectname">Flow<span id="projectnumber">&#160;2.0.0</span>
   </div>
   <div id="projectbrief">Flow project: Full implementation reference.</div>
  </td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.9.4 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
var searchBox = new SearchBox("searchBox", "search",'Search','.html');
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
  initMenu('',true,false,'search.php','Search');
  $(document).ready(function() { init_search(); });
});
/* @license-end */
</script>
<div id="main-nav"></div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0" 
        name="MSearchResults" id="MSearchResults">
</iframe>
</div>

<div id="nav-path" class="navpath">
  <ul>
<li class="navelem"><a class="el" href="namespaceflow.html">flow</a></li><li class="navelem"><a class="el" href="namespaceflow_1_1net__flow.html">net_flow</a></li><li class="navelem"><a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html">Socket_buffer</a></li>  </ul>
</div>
</div><!-- top -->
<div class="header">
  <div class="summary">
<a href="#pub-methods">Public Member Functions</a> &#124;
<a href="#pri-types">Private Types</a> &#124;
<a href="#pri-static-methods">Static Private Member Functions</a> &#124;
<a href="#pri-attribs">Private Attributes</a> &#124;
<a href="#friends">Friends</a> &#124;
<a href="classflow_1_1net__flow_1_1Socket__buffer-members.html">List of all members</a>  </div>
  <div class="headertitle"><div class="title">flow::net_flow::Socket_buffer Class Reference</div></div>
</div><!--header-->
<div class="contents">

<p>Internal <code><a class="el" href="namespaceflow_1_1net__flow.html" title="Flow module containing the API and implementation of the Flow network protocol, a TCP-inspired stream...">net_flow</a></code> class that implements a socket buffer, as used by <a class="el" href="classflow_1_1net__flow_1_1Peer__socket.html" title="A peer (non-server) socket operating over the Flow network protocol, with optional stream-of-bytes an...">Peer_socket</a> for Send and Receive buffers.  
 <a href="classflow_1_1net__flow_1_1Socket__buffer.html#details">More...</a></p>

<p><code>#include &lt;<a class="el" href="socket__buffer_8hpp_source.html">socket_buffer.hpp</a>&gt;</code></p>
<div class="dynheader">
Inheritance diagram for flow::net_flow::Socket_buffer:</div>
<div class="dyncontent">
<div class="center"><iframe scrolling="no" frameborder="0" src="classflow_1_1net__flow_1_1Socket__buffer__inherit__graph.svg" width="310" height="119"><p><b>This browser is not able to show SVG: try Firefox, Chrome, Safari, or Opera instead.</b></p></iframe>
</div>
<center><span class="legend">[<a href="graph_legend.html">legend</a>]</span></center></div>
<div class="dynheader">
Collaboration diagram for flow::net_flow::Socket_buffer:</div>
<div class="dyncontent">
<div class="center"><iframe scrolling="no" frameborder="0" src="classflow_1_1net__flow_1_1Socket__buffer__coll__graph.svg" width="1434" height="452"><p><b>This browser is not able to show SVG: try Firefox, Chrome, Safari, or Opera instead.</b></p></iframe>
</div>
<center><span class="legend">[<a href="graph_legend.html">legend</a>]</span></center></div>
<table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-methods" name="pub-methods"></a>
Public Member Functions</h2></td></tr>
<tr class="memitem:a42d219bb3431496d13b791ef6ef93934"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#a42d219bb3431496d13b791ef6ef93934">Socket_buffer</a> (<a class="el" href="classflow_1_1log_1_1Logger.html">log::Logger</a> *logger_ptr, size_t block_size_hint)</td></tr>
<tr class="memdesc:a42d219bb3431496d13b791ef6ef93934"><td class="mdescLeft">&#160;</td><td class="mdescRight">Initialize empty buffer.  <a href="classflow_1_1net__flow_1_1Socket__buffer.html#a42d219bb3431496d13b791ef6ef93934">More...</a><br /></td></tr>
<tr class="separator:a42d219bb3431496d13b791ef6ef93934"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:af21cd24bba62da1d16a8fc4f9b8e37fd"><td class="memItemLeft" align="right" valign="top">size_t&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#af21cd24bba62da1d16a8fc4f9b8e37fd">data_size</a> () const</td></tr>
<tr class="memdesc:af21cd24bba62da1d16a8fc4f9b8e37fd"><td class="mdescLeft">&#160;</td><td class="mdescRight">The total number of bytes of application-layer data stored in this object.  <a href="classflow_1_1net__flow_1_1Socket__buffer.html#af21cd24bba62da1d16a8fc4f9b8e37fd">More...</a><br /></td></tr>
<tr class="separator:af21cd24bba62da1d16a8fc4f9b8e37fd"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ac1fc9d1883bb8e6a1e28a6b7e30d90e4"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classbool.html">bool</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#ac1fc9d1883bb8e6a1e28a6b7e30d90e4">empty</a> () const</td></tr>
<tr class="memdesc:ac1fc9d1883bb8e6a1e28a6b7e30d90e4"><td class="mdescLeft">&#160;</td><td class="mdescRight">Returns true if and only if <a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#af21cd24bba62da1d16a8fc4f9b8e37fd" title="The total number of bytes of application-layer data stored in this object.">data_size()</a> == 0.  <a href="classflow_1_1net__flow_1_1Socket__buffer.html#ac1fc9d1883bb8e6a1e28a6b7e30d90e4">More...</a><br /></td></tr>
<tr class="separator:ac1fc9d1883bb8e6a1e28a6b7e30d90e4"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a69a0c514df820c36e7109fb1fcf78522"><td class="memTemplParams" colspan="2">template&lt;typename Const_buffer_sequence &gt; </td></tr>
<tr class="memitem:a69a0c514df820c36e7109fb1fcf78522"><td class="memTemplItemLeft" align="right" valign="top">size_t&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#a69a0c514df820c36e7109fb1fcf78522">feed_bufs_copy</a> (const Const_buffer_sequence &amp;data, size_t max_data_size)</td></tr>
<tr class="memdesc:a69a0c514df820c36e7109fb1fcf78522"><td class="mdescLeft">&#160;</td><td class="mdescRight">Feeds (adds to the back of the byte buffer) the contents of the byte stream composed of the bytes in the given <code>Const_buffer_sequence</code>, in the order in which they are given &ndash; up to an internal buffer size.  <a href="classflow_1_1net__flow_1_1Socket__buffer.html#a69a0c514df820c36e7109fb1fcf78522">More...</a><br /></td></tr>
<tr class="separator:a69a0c514df820c36e7109fb1fcf78522"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a689b49e578de0a3fe7d376dadf296309"><td class="memItemLeft" align="right" valign="top">size_t&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#a689b49e578de0a3fe7d376dadf296309">feed_buf_move</a> (<a class="el" href="namespaceflow_1_1util.html#af09888b3a8feaff209b6625e493bc338">util::Blob</a> *data, size_t max_data_size)</td></tr>
<tr class="memdesc:a689b49e578de0a3fe7d376dadf296309"><td class="mdescLeft">&#160;</td><td class="mdescRight">Feeds (adds to the back of the byte buffer) the byte sequence equal to the given byte sequence <code>*data</code>, up to an internal buffer size.  <a href="classflow_1_1net__flow_1_1Socket__buffer.html#a689b49e578de0a3fe7d376dadf296309">More...</a><br /></td></tr>
<tr class="separator:a689b49e578de0a3fe7d376dadf296309"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:af60133c1d6825246b54f10f26810cd88"><td class="memTemplParams" colspan="2">template&lt;typename Mutable_buffer_sequence &gt; </td></tr>
<tr class="memitem:af60133c1d6825246b54f10f26810cd88"><td class="memTemplItemLeft" align="right" valign="top">size_t&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#af60133c1d6825246b54f10f26810cd88">consume_bufs_copy</a> (const Mutable_buffer_sequence &amp;target_bufs)</td></tr>
<tr class="memdesc:af60133c1d6825246b54f10f26810cd88"><td class="mdescLeft">&#160;</td><td class="mdescRight">Consumes (removes from the front of the internal byte buffer and returns them to the caller) a byte sequence of length <a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#af21cd24bba62da1d16a8fc4f9b8e37fd" title="The total number of bytes of application-layer data stored in this object.">data_size()</a> or the available space in <code>target_bufs</code> &ndash; whichever is smaller.  <a href="classflow_1_1net__flow_1_1Socket__buffer.html#af60133c1d6825246b54f10f26810cd88">More...</a><br /></td></tr>
<tr class="separator:af60133c1d6825246b54f10f26810cd88"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a8fe3fe5f6a33cfd8fb84eb2607fbc05b"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#a8fe3fe5f6a33cfd8fb84eb2607fbc05b">consume_buf_move</a> (<a class="el" href="namespaceflow_1_1util.html#af09888b3a8feaff209b6625e493bc338">util::Blob</a> *target_buf, size_t max_data_size)</td></tr>
<tr class="memdesc:a8fe3fe5f6a33cfd8fb84eb2607fbc05b"><td class="mdescLeft">&#160;</td><td class="mdescRight">Consumes (removes from the front of the internal byte buffer and returns them to the caller) a byte sequence of length <a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#af21cd24bba62da1d16a8fc4f9b8e37fd" title="The total number of bytes of application-layer data stored in this object.">data_size()</a> or <code>max_data_size</code> &ndash; whichever is smaller.  <a href="classflow_1_1net__flow_1_1Socket__buffer.html#a8fe3fe5f6a33cfd8fb84eb2607fbc05b">More...</a><br /></td></tr>
<tr class="separator:a8fe3fe5f6a33cfd8fb84eb2607fbc05b"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a38eab6dca9f302d7e280de72dfe62c17"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#a38eab6dca9f302d7e280de72dfe62c17">clear</a> ()</td></tr>
<tr class="memdesc:a38eab6dca9f302d7e280de72dfe62c17"><td class="mdescLeft">&#160;</td><td class="mdescRight">Destroys all stored data.  <a href="classflow_1_1net__flow_1_1Socket__buffer.html#a38eab6dca9f302d7e280de72dfe62c17">More...</a><br /></td></tr>
<tr class="separator:a38eab6dca9f302d7e280de72dfe62c17"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="inherit_header pub_methods_classflow_1_1log_1_1Log__context"><td colspan="2" onclick="javascript:toggleInherit('pub_methods_classflow_1_1log_1_1Log__context')"><img src="closed.png" alt="-"/>&#160;Public Member Functions inherited from <a class="el" href="classflow_1_1log_1_1Log__context.html">flow::log::Log_context</a></td></tr>
<tr class="memitem:ae7100d2dd130d8f130e3e64fdb1f4fd9 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1log_1_1Log__context.html#ae7100d2dd130d8f130e3e64fdb1f4fd9">Log_context</a> (<a class="el" href="classflow_1_1log_1_1Logger.html">Logger</a> *logger=0)</td></tr>
<tr class="memdesc:ae7100d2dd130d8f130e3e64fdb1f4fd9 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="mdescLeft">&#160;</td><td class="mdescRight">Constructs <a class="el" href="classflow_1_1log_1_1Log__context.html" title="Convenience class that simply stores a Logger and/or Component passed into a constructor; and returns...">Log_context</a> by storing the given pointer to a <a class="el" href="classflow_1_1log_1_1Logger.html" title="Interface that the user should implement, passing the implementing Logger into logging classes (Flow&#39;...">Logger</a> and a null <a class="el" href="classflow_1_1log_1_1Component.html" title="A light-weight class, each object storing a component payload encoding an enum value from enum type o...">Component</a>.  <a href="classflow_1_1log_1_1Log__context.html#ae7100d2dd130d8f130e3e64fdb1f4fd9">More...</a><br /></td></tr>
<tr class="separator:ae7100d2dd130d8f130e3e64fdb1f4fd9 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:af1ac7f30ab442c3c6aa6079335df6c9a inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memTemplParams" colspan="2">template&lt;typename Component_payload &gt; </td></tr>
<tr class="memitem:af1ac7f30ab442c3c6aa6079335df6c9a inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memTemplItemLeft" align="right" valign="top">&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="classflow_1_1log_1_1Log__context.html#af1ac7f30ab442c3c6aa6079335df6c9a">Log_context</a> (<a class="el" href="classflow_1_1log_1_1Logger.html">Logger</a> *logger, Component_payload component_payload)</td></tr>
<tr class="memdesc:af1ac7f30ab442c3c6aa6079335df6c9a inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="mdescLeft">&#160;</td><td class="mdescRight">Constructs <a class="el" href="classflow_1_1log_1_1Log__context.html" title="Convenience class that simply stores a Logger and/or Component passed into a constructor; and returns...">Log_context</a> by storing the given pointer to a <a class="el" href="classflow_1_1log_1_1Logger.html" title="Interface that the user should implement, passing the implementing Logger into logging classes (Flow&#39;...">Logger</a> and a new <a class="el" href="classflow_1_1log_1_1Component.html" title="A light-weight class, each object storing a component payload encoding an enum value from enum type o...">Component</a> storing the specified generically typed payload (an <code>enum</code> value).  <a href="classflow_1_1log_1_1Log__context.html#af1ac7f30ab442c3c6aa6079335df6c9a">More...</a><br /></td></tr>
<tr class="separator:af1ac7f30ab442c3c6aa6079335df6c9a inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a5c57a7f44959a01ca9a1c948a6686cc0 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1log_1_1Log__context.html#a5c57a7f44959a01ca9a1c948a6686cc0">Log_context</a> (const <a class="el" href="classflow_1_1log_1_1Log__context.html">Log_context</a> &amp;src)</td></tr>
<tr class="memdesc:a5c57a7f44959a01ca9a1c948a6686cc0 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="mdescLeft">&#160;</td><td class="mdescRight">Copy constructor that stores equal <code>Logger*</code> and <a class="el" href="classflow_1_1log_1_1Component.html" title="A light-weight class, each object storing a component payload encoding an enum value from enum type o...">Component</a> values as the source.  <a href="classflow_1_1log_1_1Log__context.html#a5c57a7f44959a01ca9a1c948a6686cc0">More...</a><br /></td></tr>
<tr class="separator:a5c57a7f44959a01ca9a1c948a6686cc0 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a3d4e624833d96bdafa1485ffff472509 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1log_1_1Log__context.html#a3d4e624833d96bdafa1485ffff472509">Log_context</a> (<a class="el" href="classflow_1_1log_1_1Log__context.html">Log_context</a> &amp;&amp;src)</td></tr>
<tr class="memdesc:a3d4e624833d96bdafa1485ffff472509 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="mdescLeft">&#160;</td><td class="mdescRight">Move constructor that makes this equal to <code>src</code>, while the latter becomes as-if default-constructed.  <a href="classflow_1_1log_1_1Log__context.html#a3d4e624833d96bdafa1485ffff472509">More...</a><br /></td></tr>
<tr class="separator:a3d4e624833d96bdafa1485ffff472509 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a5d628315d5a93908d47a281980d3113e inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classflow_1_1log_1_1Log__context.html">Log_context</a> &amp;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1log_1_1Log__context.html#a5d628315d5a93908d47a281980d3113e">operator=</a> (const <a class="el" href="classflow_1_1log_1_1Log__context.html">Log_context</a> &amp;src)</td></tr>
<tr class="memdesc:a5d628315d5a93908d47a281980d3113e inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="mdescLeft">&#160;</td><td class="mdescRight">Assignment operator that behaves similarly to the copy constructor.  <a href="classflow_1_1log_1_1Log__context.html#a5d628315d5a93908d47a281980d3113e">More...</a><br /></td></tr>
<tr class="separator:a5d628315d5a93908d47a281980d3113e inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:aae857197aecba8606c32296bc7bec308 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classflow_1_1log_1_1Log__context.html">Log_context</a> &amp;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1log_1_1Log__context.html#aae857197aecba8606c32296bc7bec308">operator=</a> (<a class="el" href="classflow_1_1log_1_1Log__context.html">Log_context</a> &amp;&amp;src)</td></tr>
<tr class="memdesc:aae857197aecba8606c32296bc7bec308 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="mdescLeft">&#160;</td><td class="mdescRight">Move assignment operator that behaves similarly to the move constructor.  <a href="classflow_1_1log_1_1Log__context.html#aae857197aecba8606c32296bc7bec308">More...</a><br /></td></tr>
<tr class="separator:aae857197aecba8606c32296bc7bec308 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:aa6bb8e4250586425631ef80063caf155 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1log_1_1Log__context.html#aa6bb8e4250586425631ef80063caf155">swap</a> (<a class="el" href="classflow_1_1log_1_1Log__context.html">Log_context</a> &amp;other)</td></tr>
<tr class="memdesc:aa6bb8e4250586425631ef80063caf155 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="mdescLeft">&#160;</td><td class="mdescRight">Swaps <a class="el" href="classflow_1_1log_1_1Logger.html" title="Interface that the user should implement, passing the implementing Logger into logging classes (Flow&#39;...">Logger</a> pointers and <a class="el" href="classflow_1_1log_1_1Component.html" title="A light-weight class, each object storing a component payload encoding an enum value from enum type o...">Component</a> objects held by <code>*this</code> and <code>other</code>.  <a href="classflow_1_1log_1_1Log__context.html#aa6bb8e4250586425631ef80063caf155">More...</a><br /></td></tr>
<tr class="separator:aa6bb8e4250586425631ef80063caf155 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:af4db395042b065b00398cd59845dcb4d inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classflow_1_1log_1_1Logger.html">Logger</a> *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1log_1_1Log__context.html#af4db395042b065b00398cd59845dcb4d">get_logger</a> () const</td></tr>
<tr class="memdesc:af4db395042b065b00398cd59845dcb4d inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="mdescLeft">&#160;</td><td class="mdescRight">Returns the stored <a class="el" href="classflow_1_1log_1_1Logger.html" title="Interface that the user should implement, passing the implementing Logger into logging classes (Flow&#39;...">Logger</a> pointer, particularly as many <code>FLOW_LOG_*()</code> macros expect.  <a href="classflow_1_1log_1_1Log__context.html#af4db395042b065b00398cd59845dcb4d">More...</a><br /></td></tr>
<tr class="separator:af4db395042b065b00398cd59845dcb4d inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a8a5fef42dc2cedf3c0d1a6e83beb2948 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memItemLeft" align="right" valign="top">const <a class="el" href="classflow_1_1log_1_1Component.html">Component</a> &amp;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1log_1_1Log__context.html#a8a5fef42dc2cedf3c0d1a6e83beb2948">get_log_component</a> () const</td></tr>
<tr class="memdesc:a8a5fef42dc2cedf3c0d1a6e83beb2948 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="mdescLeft">&#160;</td><td class="mdescRight">Returns reference to the stored <a class="el" href="classflow_1_1log_1_1Component.html" title="A light-weight class, each object storing a component payload encoding an enum value from enum type o...">Component</a> object, particularly as many <code>FLOW_LOG_*()</code> macros expect.  <a href="classflow_1_1log_1_1Log__context.html#a8a5fef42dc2cedf3c0d1a6e83beb2948">More...</a><br /></td></tr>
<tr class="separator:a8a5fef42dc2cedf3c0d1a6e83beb2948 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pri-types" name="pri-types"></a>
Private Types</h2></td></tr>
<tr class="memitem:ac702b3fcb36a2aed9d129b1255dcfdbc"><td class="memItemLeft" align="right" valign="top">using&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#ac702b3fcb36a2aed9d129b1255dcfdbc">Blob_ptr</a> = boost::shared_ptr&lt; <a class="el" href="namespaceflow_1_1util.html#af09888b3a8feaff209b6625e493bc338">util::Blob</a> &gt;</td></tr>
<tr class="memdesc:ac702b3fcb36a2aed9d129b1255dcfdbc"><td class="mdescLeft">&#160;</td><td class="mdescRight">Short-hand for byte sequence on the heap. (Using ref-counted pointer purely for convenience.)  <a href="classflow_1_1net__flow_1_1Socket__buffer.html#ac702b3fcb36a2aed9d129b1255dcfdbc">More...</a><br /></td></tr>
<tr class="separator:ac702b3fcb36a2aed9d129b1255dcfdbc"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a20b11f7f884d1c811573bc2f551c8771"><td class="memItemLeft" align="right" valign="top">using&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#a20b11f7f884d1c811573bc2f551c8771">Blob_const_ptr</a> = boost::shared_ptr&lt; const <a class="el" href="namespaceflow_1_1util.html#af09888b3a8feaff209b6625e493bc338">util::Blob</a> &gt;</td></tr>
<tr class="memdesc:a20b11f7f884d1c811573bc2f551c8771"><td class="mdescLeft">&#160;</td><td class="mdescRight">Short-hand for byte sequence on the heap. (Using ref-counted pointer purely for convenience.)  <a href="classflow_1_1net__flow_1_1Socket__buffer.html#a20b11f7f884d1c811573bc2f551c8771">More...</a><br /></td></tr>
<tr class="separator:a20b11f7f884d1c811573bc2f551c8771"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a378b7a330d596f81cdf21ea0eb291c11"><td class="memItemLeft" align="right" valign="top">using&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#a378b7a330d596f81cdf21ea0eb291c11">Queue</a> = std::deque&lt; <a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#ac702b3fcb36a2aed9d129b1255dcfdbc">Blob_ptr</a> &gt;</td></tr>
<tr class="memdesc:a378b7a330d596f81cdf21ea0eb291c11"><td class="mdescLeft">&#160;</td><td class="mdescRight">FIFO of byte sequences, together comprising an overall byte sequence.  <a href="classflow_1_1net__flow_1_1Socket__buffer.html#a378b7a330d596f81cdf21ea0eb291c11">More...</a><br /></td></tr>
<tr class="separator:a378b7a330d596f81cdf21ea0eb291c11"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pri-static-methods" name="pri-static-methods"></a>
Static Private Member Functions</h2></td></tr>
<tr class="memitem:a89291fb233a05b7d449d9c3ebb802341"><td class="memTemplParams" colspan="2">template&lt;typename Const_buffer_sequence , typename Const_it &gt; </td></tr>
<tr class="memitem:a89291fb233a05b7d449d9c3ebb802341"><td class="memTemplItemLeft" align="right" valign="top">static void&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#a89291fb233a05b7d449d9c3ebb802341">copy_bytes_from_buf_seq</a> (Const_it *cur_buf_it, size_t *pos_in_buf, size_t to_copy, <a class="el" href="namespaceflow_1_1util.html#af09888b3a8feaff209b6625e493bc338">util::Blob</a> *dest_buf, util::Blob::Iterator dest)</td></tr>
<tr class="memdesc:a89291fb233a05b7d449d9c3ebb802341"><td class="mdescLeft">&#160;</td><td class="mdescRight">Helper that copies, to a given raw memory buffer, a given number of bytes from a given <code>Const_buffer_sequence</code>, starting at a given offset in a given member of that buffer sequence.  <a href="classflow_1_1net__flow_1_1Socket__buffer.html#a89291fb233a05b7d449d9c3ebb802341">More...</a><br /></td></tr>
<tr class="separator:a89291fb233a05b7d449d9c3ebb802341"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a45b5068ab3386d99ae7b27047a23ffda"><td class="memTemplParams" colspan="2">template&lt;typename Mutable_buffer_sequence , typename Const_it &gt; </td></tr>
<tr class="memitem:a45b5068ab3386d99ae7b27047a23ffda"><td class="memTemplItemLeft" align="right" valign="top">static void&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#a45b5068ab3386d99ae7b27047a23ffda">copy_bytes_to_buf_seq</a> (Const_it *cur_buf_it, size_t *pos_in_buf, size_t to_copy, const <a class="el" href="namespaceflow_1_1util.html#af09888b3a8feaff209b6625e493bc338">util::Blob</a> &amp;src_buf, util::Blob::Const_iterator src)</td></tr>
<tr class="memdesc:a45b5068ab3386d99ae7b27047a23ffda"><td class="mdescLeft">&#160;</td><td class="mdescRight">Helper that copies, to a given raw memory buffer, a given number of bytes to a given <code>Mutable_buffer_sequence</code>, starting at a given offset in a given member of that buffer sequence.  <a href="classflow_1_1net__flow_1_1Socket__buffer.html#a45b5068ab3386d99ae7b27047a23ffda">More...</a><br /></td></tr>
<tr class="separator:a45b5068ab3386d99ae7b27047a23ffda"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pri-attribs" name="pri-attribs"></a>
Private Attributes</h2></td></tr>
<tr class="memitem:ac55db5220a1349e3a6fd5d268cd8a2ed"><td class="memItemLeft" align="right" valign="top">const size_t&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#ac55db5220a1349e3a6fd5d268cd8a2ed">m_block_size_hint</a></td></tr>
<tr class="memdesc:ac55db5220a1349e3a6fd5d268cd8a2ed"><td class="mdescLeft">&#160;</td><td class="mdescRight">The max_data_size argument value that the user is predicting to use when calling <a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#a8fe3fe5f6a33cfd8fb84eb2607fbc05b" title="Consumes (removes from the front of the internal byte buffer and returns them to the caller) a byte s...">consume_buf_move()</a>; or 0 if the user intends to instead use <a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#af60133c1d6825246b54f10f26810cd88" title="Consumes (removes from the front of the internal byte buffer and returns them to the caller) a byte s...">consume_bufs_copy()</a>.  <a href="classflow_1_1net__flow_1_1Socket__buffer.html#ac55db5220a1349e3a6fd5d268cd8a2ed">More...</a><br /></td></tr>
<tr class="separator:ac55db5220a1349e3a6fd5d268cd8a2ed"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ab9d0faeeb2a8d1058b24319e8a14e52a"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#a378b7a330d596f81cdf21ea0eb291c11">Queue</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#ab9d0faeeb2a8d1058b24319e8a14e52a">m_q</a></td></tr>
<tr class="memdesc:ab9d0faeeb2a8d1058b24319e8a14e52a"><td class="mdescLeft">&#160;</td><td class="mdescRight">The data in the buffer.  <a href="classflow_1_1net__flow_1_1Socket__buffer.html#ab9d0faeeb2a8d1058b24319e8a14e52a">More...</a><br /></td></tr>
<tr class="separator:ab9d0faeeb2a8d1058b24319e8a14e52a"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a1cb77c80c42fd6b6ac86df5052f552ea"><td class="memItemLeft" align="right" valign="top">size_t&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#a1cb77c80c42fd6b6ac86df5052f552ea">m_data_size</a></td></tr>
<tr class="memdesc:a1cb77c80c42fd6b6ac86df5052f552ea"><td class="mdescLeft">&#160;</td><td class="mdescRight">The total amount of data stored, in bytes, stored in this object.  <a href="classflow_1_1net__flow_1_1Socket__buffer.html#a1cb77c80c42fd6b6ac86df5052f552ea">More...</a><br /></td></tr>
<tr class="separator:a1cb77c80c42fd6b6ac86df5052f552ea"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="friends" name="friends"></a>
Friends</h2></td></tr>
<tr class="memitem:aea121167c0d24fe6d493db2717c71a22"><td class="memItemLeft" align="right" valign="top">std::ostream &amp;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#aea121167c0d24fe6d493db2717c71a22">operator&lt;&lt;</a> (std::ostream &amp;os, const <a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html">Socket_buffer</a> &amp;sock_buf)</td></tr>
<tr class="memdesc:aea121167c0d24fe6d493db2717c71a22"><td class="mdescLeft">&#160;</td><td class="mdescRight">Prints a printable representation of the data in <code>sock_buf</code> to the given standard <code>ostream</code>.  <a href="classflow_1_1net__flow_1_1Socket__buffer.html#aea121167c0d24fe6d493db2717c71a22">More...</a><br /></td></tr>
<tr class="separator:aea121167c0d24fe6d493db2717c71a22"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table>
<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
<div class="textblock"><p >Internal <code><a class="el" href="namespaceflow_1_1net__flow.html" title="Flow module containing the API and implementation of the Flow network protocol, a TCP-inspired stream...">net_flow</a></code> class that implements a socket buffer, as used by <a class="el" href="classflow_1_1net__flow_1_1Peer__socket.html" title="A peer (non-server) socket operating over the Flow network protocol, with optional stream-of-bytes an...">Peer_socket</a> for Send and Receive buffers. </p>
<p >Users do not get direct access to such objects, but instead they access them indirectly through things like <a class="el" href="classflow_1_1net__flow_1_1Peer__socket.html#af90b656d7e0b7e746b8beb4e24717cec" title="Sends (adds to the Send buffer) the given bytes of data up to a maximum internal buffer size; and asy...">Peer_socket::send()</a> and <a class="el" href="classflow_1_1net__flow_1_1Peer__socket.html#aeb88e9253cc3f52269cb762c8e57e6d0" title="Receives (consumes from the Receive buffer) bytes of data, up to a given maximum cumulative number of...">Peer_socket::receive()</a>. Meanwhile <a class="el" href="classflow_1_1net__flow_1_1Node.html" title="An object of this class is a single Flow-protocol networking node, in the sense that: (1) it has a di...">Node</a> modifies them directly when data are received or sent over the network.</p>
<p >In terms of the API semantics, the object represents a sequence of bytes. User can enqueue bytes at the back &ndash; from either a <code>Const_buffer_sequence</code> (boost.asio style gather operation) or a vector of bytes. User can dequeue bytes from the front &ndash; to either a <code>Mutable_buffer_sequence</code> (boost.asio style scatter operation) or a vector of bytes.</p>
<p >That's all quite simple, but the complexity comes from performance aspects. The goal is to avoid copying arrays (linear-time) and encourage moving them (constant-time) whenever the user enqueues or dequeues some bytes. To that end, the class can operate in one of two modes (permanently specified at construction), tailored to high performance in the two practical use cases of the class.</p>
<h4>Mode 1: <code>block_size_hint == 0</code></h4>
<p >Intended for use as a Receive buffer. In this case, packetized blocks of data come from the network and can be of arbitrary sizes (though typically they'll be max-block-size in length if possible). They are then converted to a logical byte stream, and the user (via receive()) will dequeue them using a scatter operation. Since the size(s) of the buffer(s) the user will choose in the scatter receive() are entirely unpredictable, copying of the bytes during dequeuing is unavoidable. However, copying the packet blocks while enqueuing a packet upon receipt IS avoidable; since the <a class="el" href="classflow_1_1net__flow_1_1Node.html" title="An object of this class is a single Flow-protocol networking node, in the sense that: (1) it has a di...">Node</a> no longer needs the packet data having given it to the Receive buffer, we can take ownership of the block's data without copying.</p>
<p >In mode 1, it is expected the class user will call <a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#a689b49e578de0a3fe7d376dadf296309" title="Feeds (adds to the back of the byte buffer) the byte sequence equal to the given byte sequence *data,...">feed_buf_move()</a> for a constant-time enqueueing; and the class user will call <a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#af60133c1d6825246b54f10f26810cd88" title="Consumes (removes from the front of the internal byte buffer and returns them to the caller) a byte s...">consume_bufs_copy()</a> for a linear-time dequeuing into the end user's (<code>receive()</code> caller's) data structure.</p>
<h4>Mode 2: <code>block_size_hint &gt; 0</code></h4>
<p >Intended for use as a Send buffer. In this case, a stream of bytes comes from the end user (via <code>send()</code>), in the form of a sequence of buffers of arbitrary length/structure, which is enqueued into this object. <a class="el" href="classflow_1_1net__flow_1_1Node.html" title="An object of this class is a single Flow-protocol networking node, in the sense that: (1) it has a di...">Node</a>, when it is ready to send a packet, dequeues max-block-size bytes (or fewer, if fewer are available in <a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html" title="Internal net_flow class that implements a socket buffer, as used by Peer_socket for Send and Receive ...">Socket_buffer</a>), packetizes them, and sends them off. <a class="el" href="classflow_1_1net__flow_1_1Node.html" title="An object of this class is a single Flow-protocol networking node, in the sense that: (1) it has a di...">Node</a> will never ask for fewer than max-block-size bytes (in particular, it will not send anything until congestion window [CWND] has at least that much free space). Since the size(s) of the enqueued buffers are entirely unpredictable, copying of the bytes during enqueueing is unavoidable. However, copying the packets while dequeueing a packet to send IS avoidable. How? During enqueuing, we internally pack bytes into groups of <code>block_size_hint</code> == max-block-size bytes. Then when a packet is dequeued, we can provide a ready-made front group of bytes with a constant-time operation.</p>
<p >In mode 2, it is expected the class user will call <a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#a69a0c514df820c36e7109fb1fcf78522" title="Feeds (adds to the back of the byte buffer) the contents of the byte stream composed of the bytes in ...">feed_bufs_copy()</a> for a linear-time enqueueing from the end user's (<code>send()</code> caller's) data structure; and the class user will call <a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#a8fe3fe5f6a33cfd8fb84eb2607fbc05b" title="Consumes (removes from the front of the internal byte buffer and returns them to the caller) a byte s...">consume_buf_move()</a> for a constant-time dequeuing into a low-level packet.</p>
<p >This narrow design for performance is the reason for the kind-of-odd asymmetrical set of methods for feeding and consuming bytes. The two modes differ only in performance, and technically you may mix and match the recommended calls for the 2 modes after construction. However that defeats the point of the class, so I wouldn't recommend that.</p>
<h3>Thread safety</h3>
<p >Separate objects: All functionality safe for simultaneous execution from multiple threads. Same object: Not safe to execute a non-const operation simultaneously with any other operation; otherwise safe. Rationale: While locking of <a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html" title="Internal net_flow class that implements a socket buffer, as used by Peer_socket for Send and Receive ...">Socket_buffer</a> objects is essential, typically they must be locked together with various other external (to <a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html" title="Internal net_flow class that implements a socket buffer, as used by Peer_socket for Send and Receive ...">Socket_buffer</a>) pieces of data (such as a given <a class="el" href="classflow_1_1net__flow_1_1Peer__socket.html#a4fb8e8df98efa023e8bd4bd825475a18" title="The Error_code causing disconnection (if one has occurred or is occurring) on this socket; otherwise ...">Peer_socket::m_disconnect_cause</a>), and therefore the locking is left to the user of the class. </p>

<p class="definition">Definition at line <a class="el" href="socket__buffer_8hpp_source.html#l00095">95</a> of file <a class="el" href="socket__buffer_8hpp_source.html">socket_buffer.hpp</a>.</p>
</div><h2 class="groupheader">Member Typedef Documentation</h2>
<a id="a20b11f7f884d1c811573bc2f551c8771" name="a20b11f7f884d1c811573bc2f551c8771"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a20b11f7f884d1c811573bc2f551c8771">&#9670;&nbsp;</a></span>Blob_const_ptr</h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname">using <a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#a20b11f7f884d1c811573bc2f551c8771">flow::net_flow::Socket_buffer::Blob_const_ptr</a> =  boost::shared_ptr&lt;const <a class="el" href="namespaceflow_1_1util.html#af09888b3a8feaff209b6625e493bc338">util::Blob</a>&gt;</td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">private</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">

<p>Short-hand for byte sequence on the heap. (Using ref-counted pointer purely for convenience.) </p>

<p class="definition">Definition at line <a class="el" href="socket__buffer_8hpp_source.html#l00247">247</a> of file <a class="el" href="socket__buffer_8hpp_source.html">socket_buffer.hpp</a>.</p>

</div>
</div>
<a id="ac702b3fcb36a2aed9d129b1255dcfdbc" name="ac702b3fcb36a2aed9d129b1255dcfdbc"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ac702b3fcb36a2aed9d129b1255dcfdbc">&#9670;&nbsp;</a></span>Blob_ptr</h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname">using <a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#ac702b3fcb36a2aed9d129b1255dcfdbc">flow::net_flow::Socket_buffer::Blob_ptr</a> =  boost::shared_ptr&lt;<a class="el" href="namespaceflow_1_1util.html#af09888b3a8feaff209b6625e493bc338">util::Blob</a>&gt;</td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">private</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">

<p>Short-hand for byte sequence on the heap. (Using ref-counted pointer purely for convenience.) </p>

<p class="definition">Definition at line <a class="el" href="socket__buffer_8hpp_source.html#l00244">244</a> of file <a class="el" href="socket__buffer_8hpp_source.html">socket_buffer.hpp</a>.</p>

</div>
</div>
<a id="a378b7a330d596f81cdf21ea0eb291c11" name="a378b7a330d596f81cdf21ea0eb291c11"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a378b7a330d596f81cdf21ea0eb291c11">&#9670;&nbsp;</a></span>Queue</h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname">using <a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#a378b7a330d596f81cdf21ea0eb291c11">flow::net_flow::Socket_buffer::Queue</a> =  std::deque&lt;<a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#ac702b3fcb36a2aed9d129b1255dcfdbc">Blob_ptr</a>&gt;</td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">private</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">

<p>FIFO of byte sequences, together comprising an overall byte sequence. </p>
<p >Why not just use a <code>deque&lt;uint8_t&gt;</code>? We easily could, and it would make the code far simpler. Answer: this enables us to reduce or eliminate copying of data in certain likely use cases, chief among them when using <a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html" title="Internal net_flow class that implements a socket buffer, as used by Peer_socket for Send and Receive ...">Socket_buffer</a> as the Send buffer. See <a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#ab9d0faeeb2a8d1058b24319e8a14e52a" title="The data in the buffer.">m_q</a>.</p>
<p >Why <code>deque</code> instead of <code>list</code>? Both offer ~O(1) <code>push_back()</code> and <code>pop_front()</code>. <code>deque</code> is implemented, in practice, as a set of arrays and a master array with pointers to those arrays. <code>list</code> is a doubly-linked list. <code>deque</code> is therefore probably more compact and local in memory. <code>list</code> may perform less reallocating/copying, depending on how the <code>deque</code> implementation works. Using <code>deque</code> on a hunch, however. Note, also, that at least gcc 4+ defaults <code>queue&lt;T&gt;</code> to <code>queue&lt;T, deque&gt;</code>, so I guess they also find it better on average.</p>
<p >Using container instead of adapter <code>queue</code> due to need to iterate over the whole thing in some situations.</p>
<dl class="todo"><dt><b><a class="el" href="todo.html#_todo000073">Todo:</a></b></dt><dd>Investigate pros and cons of deque vs. list empirically. </dd></dl>

<p class="definition">Definition at line <a class="el" href="socket__buffer_8hpp_source.html#l00267">267</a> of file <a class="el" href="socket__buffer_8hpp_source.html">socket_buffer.hpp</a>.</p>

</div>
</div>
<h2 class="groupheader">Constructor &amp; Destructor Documentation</h2>
<a id="a42d219bb3431496d13b791ef6ef93934" name="a42d219bb3431496d13b791ef6ef93934"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a42d219bb3431496d13b791ef6ef93934">&#9670;&nbsp;</a></span>Socket_buffer()</h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname">flow::net_flow::Socket_buffer::Socket_buffer </td>
          <td>(</td>
          <td class="paramtype"><a class="el" href="classflow_1_1log_1_1Logger.html">log::Logger</a> *&#160;</td>
          <td class="paramname"><em>logger_ptr</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">size_t&#160;</td>
          <td class="paramname"><em>block_size_hint</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">explicit</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">

<p>Initialize empty buffer. </p>
<p >The block_size_hint argument is an important parameter that determines the algorithm used for internally storing the bytes supplied via <code>feed*()</code>. While this has NO effect on the semantics of the output of <code>consume*()</code>, it has an effect on internal performance.</p>
<p >See <a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html" title="Internal net_flow class that implements a socket buffer, as used by Peer_socket for Send and Receive ...">Socket_buffer</a> class doc header for explanation of <code>block_size_hint</code>.</p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">logger_ptr</td><td>Logger to use for subsequent logging. </td></tr>
    <tr><td class="paramname">block_size_hint</td><td>See above. </td></tr>
  </table>
  </dd>
</dl>

<p class="definition">Definition at line <a class="el" href="socket__buffer_8cpp_source.html#l00026">26</a> of file <a class="el" href="socket__buffer_8cpp_source.html">socket_buffer.cpp</a>.</p>

<p class="reference">References <a class="el" href="log_8hpp_source.html#l00227">FLOW_LOG_TRACE</a>.</p>

</div>
</div>
<h2 class="groupheader">Member Function Documentation</h2>
<a id="a38eab6dca9f302d7e280de72dfe62c17" name="a38eab6dca9f302d7e280de72dfe62c17"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a38eab6dca9f302d7e280de72dfe62c17">&#9670;&nbsp;</a></span>clear()</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">void flow::net_flow::Socket_buffer::clear </td>
          <td>(</td>
          <td class="paramname"></td><td>)</td>
          <td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Destroys all stored data. </p>

<p class="definition">Definition at line <a class="el" href="socket__buffer_8cpp_source.html#l00170">170</a> of file <a class="el" href="socket__buffer_8cpp_source.html">socket_buffer.cpp</a>.</p>

<p class="reference">References <a class="el" href="socket__buffer_8hpp_source.html#l00387">m_data_size</a>, and <a class="el" href="socket__buffer_8hpp_source.html#l00379">m_q</a>.</p>

</div>
</div>
<a id="a8fe3fe5f6a33cfd8fb84eb2607fbc05b" name="a8fe3fe5f6a33cfd8fb84eb2607fbc05b"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a8fe3fe5f6a33cfd8fb84eb2607fbc05b">&#9670;&nbsp;</a></span>consume_buf_move()</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">void flow::net_flow::Socket_buffer::consume_buf_move </td>
          <td>(</td>
          <td class="paramtype"><a class="el" href="namespaceflow_1_1util.html#af09888b3a8feaff209b6625e493bc338">util::Blob</a> *&#160;</td>
          <td class="paramname"><em>target_buf</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">size_t&#160;</td>
          <td class="paramname"><em>max_data_size</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Consumes (removes from the front of the internal byte buffer and returns them to the caller) a byte sequence of length <a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#af21cd24bba62da1d16a8fc4f9b8e37fd" title="The total number of bytes of application-layer data stored in this object.">data_size()</a> or <code>max_data_size</code> &ndash; whichever is smaller. </p>
<p >The bytes are removed from the front of the internal byte buffer and are written in the same order, starting from the first byte in <code>target_buf</code>. <code>*target_buf</code> is resized to the number of bytes thus consumed. If possible based on certain constraints, the operation avoids copying and has <em>O(1)</em> time complexity.</p>
<p >If <code>block_size_hint != 0</code>, and <a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#a8fe3fe5f6a33cfd8fb84eb2607fbc05b" title="Consumes (removes from the front of the internal byte buffer and returns them to the caller) a byte s...">consume_buf_move()</a> is always called with <code>max_data_size == block_size_hint</code>, then the time complexity is <em>O(1)</em> whenever this is called. In other uses cases this is not guaranteed, and the time complexity is <em>O(n)</em>.</p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">target_buf</td><td>Byte buffer which will be cleared and replaced with the bytes consumed from internal buffer. Therefore <code>target_buf-&gt;size()</code> can be used to know how many bytes were consumed. Performance note: <code>*target_buf</code> internal buffer may be reallocated, though this is avoided if reasonably possible (if it already has enough <code>capacity()</code>, it is not reallocated). </td></tr>
    <tr><td class="paramname">max_data_size</td><td><a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#af21cd24bba62da1d16a8fc4f9b8e37fd" title="The total number of bytes of application-layer data stored in this object.">data_size()</a> will not grow beyond this. </td></tr>
  </table>
  </dd>
</dl>

<p class="definition">Definition at line <a class="el" href="socket__buffer_8cpp_source.html#l00103">103</a> of file <a class="el" href="socket__buffer_8cpp_source.html">socket_buffer.cpp</a>.</p>

<p class="reference">References <a class="el" href="util_2util_8hpp_source.html#l00506">flow::util::buffers_dump_string()</a>, <a class="el" href="socket__buffer_8hpp_source.html#l00548">consume_bufs_copy()</a>, <a class="el" href="log_8hpp_source.html#l00242">FLOW_LOG_DATA</a>, <a class="el" href="log_8hpp_source.html#l00227">FLOW_LOG_TRACE</a>, <a class="el" href="socket__buffer_8hpp_source.html#l00387">m_data_size</a>, and <a class="el" href="socket__buffer_8hpp_source.html#l00379">m_q</a>.</p>

<p class="reference">Referenced by <a class="el" href="peer__socket_8cpp_source.html#l04721">flow::net_flow::Node::send_worker()</a>.</p>
<div class="dynheader">
Here is the call graph for this function:</div>
<div class="dyncontent">
<div class="center"><iframe scrolling="no" frameborder="0" src="classflow_1_1net__flow_1_1Socket__buffer_a8fe3fe5f6a33cfd8fb84eb2607fbc05b_cgraph.svg" width="736" height="107"><p><b>This browser is not able to show SVG: try Firefox, Chrome, Safari, or Opera instead.</b></p></iframe>
</div>
</div>
<div class="dynheader">
Here is the caller graph for this function:</div>
<div class="dyncontent">
<div class="center"><iframe scrolling="no" frameborder="0" src="classflow_1_1net__flow_1_1Socket__buffer_a8fe3fe5f6a33cfd8fb84eb2607fbc05b_icgraph.svg" width="978" height="107"><p><b>This browser is not able to show SVG: try Firefox, Chrome, Safari, or Opera instead.</b></p></iframe>
</div>
</div>

</div>
</div>
<a id="af60133c1d6825246b54f10f26810cd88" name="af60133c1d6825246b54f10f26810cd88"></a>
<h2 class="memtitle"><span class="permalink"><a href="#af60133c1d6825246b54f10f26810cd88">&#9670;&nbsp;</a></span>consume_bufs_copy()</h2>

<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;typename Mutable_buffer_sequence &gt; </div>
      <table class="memname">
        <tr>
          <td class="memname">size_t flow::net_flow::Socket_buffer::consume_bufs_copy </td>
          <td>(</td>
          <td class="paramtype">const Mutable_buffer_sequence &amp;&#160;</td>
          <td class="paramname"><em>target_bufs</em></td><td>)</td>
          <td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Consumes (removes from the front of the internal byte buffer and returns them to the caller) a byte sequence of length <a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#af21cd24bba62da1d16a8fc4f9b8e37fd" title="The total number of bytes of application-layer data stored in this object.">data_size()</a> or the available space in <code>target_bufs</code> &ndash; whichever is smaller. </p>
<p >The bytes are removed from the front of the internal byte buffer and are written in the same order, starting from the first byte in <code>target_bufs</code>. The operation involves a copy and has <em>O(n)</em> time complexity.</p>
<dl class="tparams"><dt>Template Parameters</dt><dd>
  <table class="tparams">
    <tr><td class="paramname">Mutable_buffer_sequence</td><td>Type that models the boost.asio <code>MutableBufferSequence</code> concept (see Boost docs). Basically, it's any container with elements convertible to <code>boost::asio::mutable_buffer</code>; and bidirectional iterator support. Examples: <code>vector&lt;mutable_buffer&gt;</code>, <code>list&lt;mutable_buffer&gt;.</code> Why allow <code>mutable_buffer</code> instead of, say, <code>Sequence</code> of bytes? Same reason as boost.asio's receive functions: it allows a great amount of flexibility without sacrificing performance, since <code>boost::asio::buffer()</code> function can adapt lots of different objects (arrays, <code>vector</code>s, <code>string</code>s, and more of bytes, integers, and more). </td></tr>
  </table>
  </dd>
</dl>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">target_bufs</td><td>Buffer sequence into which to copy bytes. </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>Number of bytes (possibly zero) by which <a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#af21cd24bba62da1d16a8fc4f9b8e37fd" title="The total number of bytes of application-layer data stored in this object.">data_size()</a> decreased, which equals the # of bytes copied into <code>target_bufs</code>. This is quite important &ndash; without it there is absolutely no way to know how much of <code>target_bufs</code> we've used up. </dd></dl>

<p class="definition">Definition at line <a class="el" href="socket__buffer_8hpp_source.html#l00548">548</a> of file <a class="el" href="socket__buffer_8hpp_source.html">socket_buffer.hpp</a>.</p>

<p class="reference">References <a class="el" href="util_2util_8hpp_source.html#l00506">flow::util::buffers_dump_string()</a>, <a class="el" href="log_8hpp_source.html#l00242">FLOW_LOG_DATA</a>, <a class="el" href="log_8hpp_source.html#l00227">FLOW_LOG_TRACE</a>, <a class="el" href="socket__buffer_8hpp_source.html#l00387">m_data_size</a>, and <a class="el" href="socket__buffer_8hpp_source.html#l00379">m_q</a>.</p>

<p class="reference">Referenced by <a class="el" href="socket__buffer_8cpp_source.html#l00103">consume_buf_move()</a>, <a class="el" href="peer__socket_8hpp_source.html#l02536">flow::net_flow::Peer_socket::receive()</a>, and <a class="el" href="peer__socket_8hpp_source.html#l02591">flow::net_flow::Peer_socket::sync_receive_impl()</a>.</p>
<div class="dynheader">
Here is the call graph for this function:</div>
<div class="dyncontent">
<div class="center"><iframe scrolling="no" frameborder="0" src="classflow_1_1net__flow_1_1Socket__buffer_af60133c1d6825246b54f10f26810cd88_cgraph.svg" width="514" height="107"><p><b>This browser is not able to show SVG: try Firefox, Chrome, Safari, or Opera instead.</b></p></iframe>
</div>
</div>
<div class="dynheader">
Here is the caller graph for this function:</div>
<div class="dyncontent">
<div class="center"><iframe scrolling="no" frameborder="0" src="classflow_1_1net__flow_1_1Socket__buffer_af60133c1d6825246b54f10f26810cd88_icgraph.svg" width="1000" height="167"><p><b>This browser is not able to show SVG: try Firefox, Chrome, Safari, or Opera instead.</b></p></iframe>
</div>
</div>

</div>
</div>
<a id="a89291fb233a05b7d449d9c3ebb802341" name="a89291fb233a05b7d449d9c3ebb802341"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a89291fb233a05b7d449d9c3ebb802341">&#9670;&nbsp;</a></span>copy_bytes_from_buf_seq()</h2>

<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;typename Const_buffer_sequence , typename Const_it &gt; </div>
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname">void flow::net_flow::Socket_buffer::copy_bytes_from_buf_seq </td>
          <td>(</td>
          <td class="paramtype">Const_it *&#160;</td>
          <td class="paramname"><em>cur_buf_it</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">size_t *&#160;</td>
          <td class="paramname"><em>pos_in_buf</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">size_t&#160;</td>
          <td class="paramname"><em>to_copy</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype"><a class="el" href="namespaceflow_1_1util.html#af09888b3a8feaff209b6625e493bc338">util::Blob</a> *&#160;</td>
          <td class="paramname"><em>dest_buf</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">util::Blob::Iterator&#160;</td>
          <td class="paramname"><em>dest</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">static</span><span class="mlabel">private</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">

<p>Helper that copies, to a given raw memory buffer, a given number of bytes from a given <code>Const_buffer_sequence</code>, starting at a given offset in a given member of that buffer sequence. </p>
<p >It uses <code>memcpy()</code> or similar for copying and makes as few calls to it as possible. It is similar to the <code>boost::asio::buffer_copy(ConstBufferSequence -&gt; buffer)</code> function but also returns the logical pointers just past the last byte copied, so that this can be resumed into some other target buffer. Of course there's a <code>buffer_copy(ConstBufferSequence -&gt; MutableBufferSequence)</code> that would do this, but it would be inefficient for us to have to create a <code>MutableBufferSequence</code>.</p>
<dl class="todo"><dt><b><a class="el" href="todo.html#_todo000074">Todo:</a></b></dt><dd>It would not be crazy to move <a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#a89291fb233a05b7d449d9c3ebb802341" title="Helper that copies, to a given raw memory buffer, a given number of bytes from a given Const_buffer_s...">copy_bytes_from_buf_seq()</a> and <a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#a45b5068ab3386d99ae7b27047a23ffda" title="Helper that copies, to a given raw memory buffer, a given number of bytes to a given Mutable_buffer_s...">copy_bytes_to_buf_seq()</a> into <a class="el" href="namespaceflow_1_1util.html#af09888b3a8feaff209b6625e493bc338" title="A concrete Blob_with_log_context that compile-time-disables Basic_blob::share() and the sharing API d...">util::Blob</a> to make it more widely available, though as of this writing there is no demand for this: perhaps a buffer-sequence version of <code>util::Blob::emplace_copy()</code> and in the other direction. In that case <code>util::Blob::assign_copy()</code> and all single-buffer <a class="el" href="namespaceflow_1_1util.html#af09888b3a8feaff209b6625e493bc338" title="A concrete Blob_with_log_context that compile-time-disables Basic_blob::share() and the sharing API d...">util::Blob</a> methods should probably be similarly generalized (overloaded).</dd></dl>
<dl class="tparams"><dt>Template Parameters</dt><dd>
  <table class="tparams">
    <tr><td class="paramname">Const_buffer_sequence</td><td>See user-facing APIs. </td></tr>
    <tr><td class="paramname">Const_it</td><td>Iterator type suitable for traversing <code>Const_buffer_sequence</code>. </td></tr>
  </table>
  </dd>
</dl>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">cur_buf_it</td><td>Pointer to iterator to the buffer in the buffer sequence from where to begin copying. When function returns, <code>*cur_buf_it</code> will point to the buffer containing the last byte that was copied. This can be passed to this method again to resume copying where we left off. </td></tr>
    <tr><td class="paramname">pos_in_buf</td><td>Pointer to offset, in bytes, from the start of <code>**cur_buf_it</code> from where to resume copying. This must be <code>&lt;= (*cur_buf_it)-&gt;size()</code>. If they are equal (i.e., it points just past the last byte of <code>**cur_buf_it</code>), we will properly copy from the start of the next buffer. (This can happen if the last call to the same method copied exactly through the end of a buffer in the buffer sequence, and then you call this method again with the resulting <code>*cur_buf_it</code> and <code>*pos_in_buf</code>.) </td></tr>
    <tr><td class="paramname">to_copy</td><td>The number of bytes to copy. The remainder of the buffer sequence (from <code>cur_buf_it</code>/<code>pos_in_buf</code> position) MUST contain at least that many bytes. This means you MUST determine the total byte size of the overall buffer sequence before calling this function. </td></tr>
    <tr><td class="paramname">dest_buf</td><td>(Pointer to) buffer containing <code>dest</code> location; data will be written into it. Must be of sufficient size, or behavior is undefined. </td></tr>
    <tr><td class="paramname">dest</td><td>Pointer to the location where bytes will be copied. </td></tr>
  </table>
  </dd>
</dl>

<p class="definition">Definition at line <a class="el" href="socket__buffer_8hpp_source.html#l00629">629</a> of file <a class="el" href="socket__buffer_8hpp_source.html">socket_buffer.hpp</a>.</p>

</div>
</div>
<a id="a45b5068ab3386d99ae7b27047a23ffda" name="a45b5068ab3386d99ae7b27047a23ffda"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a45b5068ab3386d99ae7b27047a23ffda">&#9670;&nbsp;</a></span>copy_bytes_to_buf_seq()</h2>

<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;typename Mutable_buffer_sequence , typename Const_it &gt; </div>
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname">void flow::net_flow::Socket_buffer::copy_bytes_to_buf_seq </td>
          <td>(</td>
          <td class="paramtype">Const_it *&#160;</td>
          <td class="paramname"><em>cur_buf_it</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">size_t *&#160;</td>
          <td class="paramname"><em>pos_in_buf</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">size_t&#160;</td>
          <td class="paramname"><em>to_copy</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">const <a class="el" href="namespaceflow_1_1util.html#af09888b3a8feaff209b6625e493bc338">util::Blob</a> &amp;&#160;</td>
          <td class="paramname"><em>src_buf</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">util::Blob::Const_iterator&#160;</td>
          <td class="paramname"><em>src</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">static</span><span class="mlabel">private</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">

<p>Helper that copies, to a given raw memory buffer, a given number of bytes to a given <code>Mutable_buffer_sequence</code>, starting at a given offset in a given member of that buffer sequence. </p>
<p >It uses <code>memcpy()</code> or similar for copying and makes as few calls to it as possible. It is the opposite of <a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#a89291fb233a05b7d449d9c3ebb802341" title="Helper that copies, to a given raw memory buffer, a given number of bytes from a given Const_buffer_s...">copy_bytes_from_buf_seq()</a>.</p>
<dl class="tparams"><dt>Template Parameters</dt><dd>
  <table class="tparams">
    <tr><td class="paramname">Mutable_buffer_sequence</td><td>See user-facing APIs. </td></tr>
    <tr><td class="paramname">Const_it</td><td>Iterator type suitable for traversing <code>Mutable_buffer_sequence</code>. </td></tr>
  </table>
  </dd>
</dl>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">cur_buf_it</td><td>See <a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#a89291fb233a05b7d449d9c3ebb802341" title="Helper that copies, to a given raw memory buffer, a given number of bytes from a given Const_buffer_s...">copy_bytes_from_buf_seq()</a>. </td></tr>
    <tr><td class="paramname">pos_in_buf</td><td>See <a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#a89291fb233a05b7d449d9c3ebb802341" title="Helper that copies, to a given raw memory buffer, a given number of bytes from a given Const_buffer_s...">copy_bytes_from_buf_seq()</a>. </td></tr>
    <tr><td class="paramname">to_copy</td><td>See <a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#a89291fb233a05b7d449d9c3ebb802341" title="Helper that copies, to a given raw memory buffer, a given number of bytes from a given Const_buffer_s...">copy_bytes_from_buf_seq()</a>. </td></tr>
    <tr><td class="paramname">src_buf</td><td>Buffer containing <code>src</code> location Must be of sufficient size, or behavior is undefined. </td></tr>
    <tr><td class="paramname">src</td><td>Pointer to the location from where bytes will be copied. </td></tr>
  </table>
  </dd>
</dl>

<p class="definition">Definition at line <a class="el" href="socket__buffer_8hpp_source.html#l00673">673</a> of file <a class="el" href="socket__buffer_8hpp_source.html">socket_buffer.hpp</a>.</p>

</div>
</div>
<a id="af21cd24bba62da1d16a8fc4f9b8e37fd" name="af21cd24bba62da1d16a8fc4f9b8e37fd"></a>
<h2 class="memtitle"><span class="permalink"><a href="#af21cd24bba62da1d16a8fc4f9b8e37fd">&#9670;&nbsp;</a></span>data_size()</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">size_t flow::net_flow::Socket_buffer::data_size </td>
          <td>(</td>
          <td class="paramname"></td><td>)</td>
          <td> const</td>
        </tr>
      </table>
</div><div class="memdoc">

<p>The total number of bytes of application-layer data stored in this object. </p>
<p >Intended use case: estimate of memory usage of this object.</p>
<p >Note: this only counts the actual user bytes fed into the buffer &ndash; not other internal book-keeping. For example, if the internal storage is a doubly-linked list of byte arrays, this will not count the memory used by the previous and next pointers for each node. Rationale: if we give control over the maximum size to the <code><a class="el" href="namespaceflow_1_1net__flow.html" title="Flow module containing the API and implementation of the Flow network protocol, a TCP-inspired stream...">net_flow</a></code> user, with these semantics it is easier to express and implement what that limit means (even if some side data are not counted as a result).</p>
<dl class="section return"><dt>Returns</dt><dd>See above. </dd></dl>

<p class="definition">Definition at line <a class="el" href="socket__buffer_8cpp_source.html#l00034">34</a> of file <a class="el" href="socket__buffer_8cpp_source.html">socket_buffer.cpp</a>.</p>

<p class="reference">References <a class="el" href="socket__buffer_8hpp_source.html#l00387">m_data_size</a>.</p>

<p class="reference">Referenced by <a class="el" href="peer__socket_8cpp_source.html#l04721">flow::net_flow::Node::send_worker()</a>.</p>
<div class="dynheader">
Here is the caller graph for this function:</div>
<div class="dyncontent">
<div class="center"><iframe scrolling="no" frameborder="0" src="classflow_1_1net__flow_1_1Socket__buffer_af21cd24bba62da1d16a8fc4f9b8e37fd_icgraph.svg" width="946" height="107"><p><b>This browser is not able to show SVG: try Firefox, Chrome, Safari, or Opera instead.</b></p></iframe>
</div>
</div>

</div>
</div>
<a id="ac1fc9d1883bb8e6a1e28a6b7e30d90e4" name="ac1fc9d1883bb8e6a1e28a6b7e30d90e4"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ac1fc9d1883bb8e6a1e28a6b7e30d90e4">&#9670;&nbsp;</a></span>empty()</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname"><a class="el" href="classbool.html">bool</a> flow::net_flow::Socket_buffer::empty </td>
          <td>(</td>
          <td class="paramname"></td><td>)</td>
          <td> const</td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Returns true if and only if <a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#af21cd24bba62da1d16a8fc4f9b8e37fd" title="The total number of bytes of application-layer data stored in this object.">data_size()</a> == 0. </p>
<dl class="section return"><dt>Returns</dt><dd>Ditto. </dd></dl>

<p class="definition">Definition at line <a class="el" href="socket__buffer_8cpp_source.html#l00165">165</a> of file <a class="el" href="socket__buffer_8cpp_source.html">socket_buffer.cpp</a>.</p>

<p class="reference">References <a class="el" href="socket__buffer_8hpp_source.html#l00387">m_data_size</a>.</p>

</div>
</div>
<a id="a689b49e578de0a3fe7d376dadf296309" name="a689b49e578de0a3fe7d376dadf296309"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a689b49e578de0a3fe7d376dadf296309">&#9670;&nbsp;</a></span>feed_buf_move()</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">size_t flow::net_flow::Socket_buffer::feed_buf_move </td>
          <td>(</td>
          <td class="paramtype"><a class="el" href="namespaceflow_1_1util.html#af09888b3a8feaff209b6625e493bc338">util::Blob</a> *&#160;</td>
          <td class="paramname"><em>data</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">size_t&#160;</td>
          <td class="paramname"><em>max_data_size</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Feeds (adds to the back of the byte buffer) the byte sequence equal to the given byte sequence <code>*data</code>, up to an internal buffer size. </p>
<p >Any bytes thus fed are cleared from the given buffer. Internally, as much as possible while following the described <code>block_size_hint</code> constraints and the <code>max_data_size</code> constraint, move semantics are used, attempting to keep time complexity at <em>O(1)</em>.</p>
<p >As many bytes as possible are taken, subject to the constraint <code><a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#af21cd24bba62da1d16a8fc4f9b8e37fd" title="The total number of bytes of application-layer data stored in this object.">data_size()</a> &lt;= max_data_size</code>. In particular if this is already untrue, no bytes are taken. If <code>block_size_hint == 0</code>, and <code><a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#af21cd24bba62da1d16a8fc4f9b8e37fd" title="The total number of bytes of application-layer data stored in this object.">data_size()</a> + data-&gt;size() &lt;= max_data_size</code>, then time complexity is constant. Otherwise it is linear in <code>data-&gt;size()</code>.</p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">data</td><td>Bytes will be moved from this byte byffer until exhausted or <a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#af21cd24bba62da1d16a8fc4f9b8e37fd" title="The total number of bytes of application-layer data stored in this object.">data_size()</a> equals <code>max_data_size</code>; the bytes thus moved are <code>erase()</code>d from <code>*data</code>. Why make this a <code>vector</code> of bytes, and not a <code>const_buffer</code>? Because this allows us to use move semantics to avoid a copy. </td></tr>
    <tr><td class="paramname">max_data_size</td><td>See above. </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>Number of bytes (possibly zero) by which <a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#af21cd24bba62da1d16a8fc4f9b8e37fd" title="The total number of bytes of application-layer data stored in this object.">data_size()</a> increased, which equals # of bytes by which <code>data-&gt;size()</code> decreased. </dd></dl>

<p class="definition">Definition at line <a class="el" href="socket__buffer_8cpp_source.html#l00039">39</a> of file <a class="el" href="socket__buffer_8cpp_source.html">socket_buffer.cpp</a>.</p>

<p class="reference">References <a class="el" href="util_2util_8hpp_source.html#l00506">flow::util::buffers_dump_string()</a>, <a class="el" href="socket__buffer_8hpp_source.html#l00395">feed_bufs_copy()</a>, <a class="el" href="log_8hpp_source.html#l00242">FLOW_LOG_DATA</a>, <a class="el" href="log_8hpp_source.html#l00227">FLOW_LOG_TRACE</a>, <a class="el" href="log_8cpp_source.html#l00217">flow::log::Log_context::get_logger()</a>, <a class="el" href="socket__buffer_8hpp_source.html#l00356">m_block_size_hint</a>, <a class="el" href="socket__buffer_8hpp_source.html#l00387">m_data_size</a>, and <a class="el" href="socket__buffer_8hpp_source.html#l00379">m_q</a>.</p>
<div class="dynheader">
Here is the call graph for this function:</div>
<div class="dyncontent">
<div class="center"><iframe scrolling="no" frameborder="0" src="classflow_1_1net__flow_1_1Socket__buffer_a689b49e578de0a3fe7d376dadf296309_cgraph.svg" width="715" height="151"><p><b>This browser is not able to show SVG: try Firefox, Chrome, Safari, or Opera instead.</b></p></iframe>
</div>
</div>

</div>
</div>
<a id="a69a0c514df820c36e7109fb1fcf78522" name="a69a0c514df820c36e7109fb1fcf78522"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a69a0c514df820c36e7109fb1fcf78522">&#9670;&nbsp;</a></span>feed_bufs_copy()</h2>

<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;typename Const_buffer_sequence &gt; </div>
      <table class="memname">
        <tr>
          <td class="memname">size_t flow::net_flow::Socket_buffer::feed_bufs_copy </td>
          <td>(</td>
          <td class="paramtype">const Const_buffer_sequence &amp;&#160;</td>
          <td class="paramname"><em>data</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">size_t&#160;</td>
          <td class="paramname"><em>max_data_size</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Feeds (adds to the back of the byte buffer) the contents of the byte stream composed of the bytes in the given <code>Const_buffer_sequence</code>, in the order in which they are given &ndash; up to an internal buffer size. </p>
<p >The data are copied (O(n)) and not modified.</p>
<p >As many bytes as possible are copied, subject to the constraint <code><a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#af21cd24bba62da1d16a8fc4f9b8e37fd" title="The total number of bytes of application-layer data stored in this object.">data_size()</a> &lt;= max_data_size</code>. In particular if this is already untrue, no bytes are copied.</p>
<dl class="tparams"><dt>Template Parameters</dt><dd>
  <table class="tparams">
    <tr><td class="paramname">Const_buffer_sequence</td><td>Type that models the boost.asio <code>ConstBufferSequence</code> concept (see Boost docs). Basically, it's any container with elements convertible to <code>boost::asio::const_buffer</code>; and bidirectional iterator support. Examples: <code>vector&lt;const_buffer&gt;</code>, <code>list&lt;const_buffer&gt;</code>. Why allow <code>const_buffer</code> instead of, say, <code>Sequence</code> of bytes? Same reason as boost.asio's send functions: it allows a great amount of flexibility without sacrificing performance, since <code>boost::asio::buffer()</code> function can adapt lots of different objects (arrays, vectors, strings, and more of bytes, integers, and more). </td></tr>
  </table>
  </dd>
</dl>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">data</td><td>Bytes will be copied from this buffer sequence until exhausted or <a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#af21cd24bba62da1d16a8fc4f9b8e37fd" title="The total number of bytes of application-layer data stored in this object.">data_size()</a> equals <code>max_data_size</code>. </td></tr>
    <tr><td class="paramname">max_data_size</td><td>See above. </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>Number of bytes (possibly zero) by which <a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#af21cd24bba62da1d16a8fc4f9b8e37fd" title="The total number of bytes of application-layer data stored in this object.">data_size()</a> increased. </dd></dl>

<p class="definition">Definition at line <a class="el" href="socket__buffer_8hpp_source.html#l00395">395</a> of file <a class="el" href="socket__buffer_8hpp_source.html">socket_buffer.hpp</a>.</p>

<p class="reference">References <a class="el" href="util_2util_8hpp_source.html#l00506">flow::util::buffers_dump_string()</a>, <a class="el" href="log_8hpp_source.html#l00242">FLOW_LOG_DATA</a>, <a class="el" href="log_8hpp_source.html#l00227">FLOW_LOG_TRACE</a>, <a class="el" href="log_8cpp_source.html#l00217">flow::log::Log_context::get_logger()</a>, <a class="el" href="socket__buffer_8hpp_source.html#l00356">m_block_size_hint</a>, <a class="el" href="socket__buffer_8hpp_source.html#l00387">m_data_size</a>, and <a class="el" href="socket__buffer_8hpp_source.html#l00379">m_q</a>.</p>

<p class="reference">Referenced by <a class="el" href="socket__buffer_8cpp_source.html#l00039">feed_buf_move()</a>, <a class="el" href="peer__socket_8hpp_source.html#l02439">flow::net_flow::Peer_socket::send()</a>, and <a class="el" href="peer__socket_8hpp_source.html#l02506">flow::net_flow::Peer_socket::sync_send_impl()</a>.</p>
<div class="dynheader">
Here is the call graph for this function:</div>
<div class="dyncontent">
<div class="center"><iframe scrolling="no" frameborder="0" src="classflow_1_1net__flow_1_1Socket__buffer_a69a0c514df820c36e7109fb1fcf78522_cgraph.svg" width="516" height="136"><p><b>This browser is not able to show SVG: try Firefox, Chrome, Safari, or Opera instead.</b></p></iframe>
</div>
</div>
<div class="dynheader">
Here is the caller graph for this function:</div>
<div class="dyncontent">
<div class="center"><iframe scrolling="no" frameborder="0" src="classflow_1_1net__flow_1_1Socket__buffer_a69a0c514df820c36e7109fb1fcf78522_icgraph.svg" width="544" height="167"><p><b>This browser is not able to show SVG: try Firefox, Chrome, Safari, or Opera instead.</b></p></iframe>
</div>
</div>

</div>
</div>
<h2 class="groupheader">Friends And Related Function Documentation</h2>
<a id="aea121167c0d24fe6d493db2717c71a22" name="aea121167c0d24fe6d493db2717c71a22"></a>
<h2 class="memtitle"><span class="permalink"><a href="#aea121167c0d24fe6d493db2717c71a22">&#9670;&nbsp;</a></span>operator&lt;&lt;</h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname">std::ostream &amp; operator&lt;&lt; </td>
          <td>(</td>
          <td class="paramtype">std::ostream &amp;&#160;</td>
          <td class="paramname"><em>os</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">const <a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html">Socket_buffer</a> &amp;&#160;</td>
          <td class="paramname"><em>sock_buf</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">friend</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">

<p>Prints a printable representation of the data in <code>sock_buf</code> to the given standard <code>ostream</code>. </p>
<p >Exactly one line per block is used. This implementation is slow; use only in DATA logging, or where performance does not matter.</p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">os</td><td>Stream to which to write. </td></tr>
    <tr><td class="paramname">sock_buf</td><td>Object to serialize. </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd><code>os</code>. </dd></dl>

<p class="definition">Definition at line <a class="el" href="socket__buffer_8cpp_source.html#l00176">176</a> of file <a class="el" href="socket__buffer_8cpp_source.html">socket_buffer.cpp</a>.</p>

</div>
</div>
<h2 class="groupheader">Member Data Documentation</h2>
<a id="ac55db5220a1349e3a6fd5d268cd8a2ed" name="ac55db5220a1349e3a6fd5d268cd8a2ed"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ac55db5220a1349e3a6fd5d268cd8a2ed">&#9670;&nbsp;</a></span>m_block_size_hint</h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname">const size_t flow::net_flow::Socket_buffer::m_block_size_hint</td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">private</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">

<p>The max_data_size argument value that the user is predicting to use when calling <a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#a8fe3fe5f6a33cfd8fb84eb2607fbc05b" title="Consumes (removes from the front of the internal byte buffer and returns them to the caller) a byte s...">consume_buf_move()</a>; or 0 if the user intends to instead use <a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#af60133c1d6825246b54f10f26810cd88" title="Consumes (removes from the front of the internal byte buffer and returns them to the caller) a byte s...">consume_bufs_copy()</a>. </p>
<p >This is explored in detail in the class doc header. Basically this should be 0, when this <a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html" title="Internal net_flow class that implements a socket buffer, as used by Peer_socket for Send and Receive ...">Socket_buffer</a> is used as a Receive buffer; and it should be set to max-block-size, when this <a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html" title="Internal net_flow class that implements a socket buffer, as used by Peer_socket for Send and Receive ...">Socket_buffer</a> is used as a Send buffer. </p>

<p class="definition">Definition at line <a class="el" href="socket__buffer_8hpp_source.html#l00356">356</a> of file <a class="el" href="socket__buffer_8hpp_source.html">socket_buffer.hpp</a>.</p>

<p class="reference">Referenced by <a class="el" href="socket__buffer_8cpp_source.html#l00039">feed_buf_move()</a>, and <a class="el" href="socket__buffer_8hpp_source.html#l00395">feed_bufs_copy()</a>.</p>

</div>
</div>
<a id="a1cb77c80c42fd6b6ac86df5052f552ea" name="a1cb77c80c42fd6b6ac86df5052f552ea"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a1cb77c80c42fd6b6ac86df5052f552ea">&#9670;&nbsp;</a></span>m_data_size</h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname">size_t flow::net_flow::Socket_buffer::m_data_size</td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">private</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">

<p>The total amount of data stored, in bytes, stored in this object. </p>
<dl class="section see"><dt>See also</dt><dd><a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#af21cd24bba62da1d16a8fc4f9b8e37fd" title="The total number of bytes of application-layer data stored in this object.">data_size()</a> for more discussion.</dd></dl>
<p>Invariant: <code>m_data_size</code> = sum(<code>m-&gt;size()</code>: for all <code>m</code> in <code>m_q</code>). </p>

<p class="definition">Definition at line <a class="el" href="socket__buffer_8hpp_source.html#l00387">387</a> of file <a class="el" href="socket__buffer_8hpp_source.html">socket_buffer.hpp</a>.</p>

<p class="reference">Referenced by <a class="el" href="socket__buffer_8cpp_source.html#l00170">clear()</a>, <a class="el" href="socket__buffer_8cpp_source.html#l00103">consume_buf_move()</a>, <a class="el" href="socket__buffer_8hpp_source.html#l00548">consume_bufs_copy()</a>, <a class="el" href="socket__buffer_8cpp_source.html#l00034">data_size()</a>, <a class="el" href="socket__buffer_8cpp_source.html#l00165">empty()</a>, <a class="el" href="socket__buffer_8cpp_source.html#l00039">feed_buf_move()</a>, and <a class="el" href="socket__buffer_8hpp_source.html#l00395">feed_bufs_copy()</a>.</p>

</div>
</div>
<a id="ab9d0faeeb2a8d1058b24319e8a14e52a" name="ab9d0faeeb2a8d1058b24319e8a14e52a"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ab9d0faeeb2a8d1058b24319e8a14e52a">&#9670;&nbsp;</a></span>m_q</h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname"><a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#a378b7a330d596f81cdf21ea0eb291c11">Queue</a> flow::net_flow::Socket_buffer::m_q</td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">private</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">

<p>The data in the buffer. </p>
<p >The logical byte sequence, as visible to the outside user of the class, is obtained as follows: iterate through range [<code>m_q[0]-&gt;begin()</code>, <code>m_q[0]-&gt;end()</code>); iterate through range [<code>m_q[1]-&gt;begin()</code>, <code>m_q[1]-&gt;end()</code>); ...; etc. <code>shared_ptr</code>s, instead of raw pointers, are used as elements just to avoid having to delete. Pointers are stored instead of direct vector objects to avoid any wholesale copying by the <code>deque</code> machinery.</p>
<p >Why not just use a queue of bytes then? The code would be far simpler. Answer: the chief use case is if <a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html" title="Internal net_flow class that implements a socket buffer, as used by Peer_socket for Send and Receive ...">Socket_buffer</a> is Send buffer, so they'll set <code>block_size_hint == N</code> and use <a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#a69a0c514df820c36e7109fb1fcf78522" title="Feeds (adds to the back of the byte buffer) the contents of the byte stream composed of the bytes in ...">feed_bufs_copy()</a> whenever <a class="el" href="classflow_1_1net__flow_1_1Peer__socket.html#af90b656d7e0b7e746b8beb4e24717cec" title="Sends (adds to the Send buffer) the given bytes of data up to a maximum internal buffer size; and asy...">Peer_socket::send()</a> is called. Then we will always <code>reserve()</code> <code>N</code> bytes in each <code>Blob</code> in <a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#ab9d0faeeb2a8d1058b24319e8a14e52a" title="The data in the buffer.">m_q</a>; as <code>feed*()</code> is called, we will fill up the last <code>Blob</code> sequence until all <code>N</code> bytes are exhausted, in which case we'll <code>push_back()</code> another <code>N</code>-capacity <code>Blob</code> sequence and fill that one as needed, etc. Since <code>send()</code> always copies bytes from user's buffer(s) anyway, we're not adding any extra copying (only the allocation behavior is different than if we'd used a simple byte buffer instead). Now, when the <a class="el" href="classflow_1_1net__flow_1_1Node.html" title="An object of this class is a single Flow-protocol networking node, in the sense that: (1) it has a di...">Node</a> needs to packetize a packet to send, with <code>max-block-size == N</code>, it will use <a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#a8fe3fe5f6a33cfd8fb84eb2607fbc05b" title="Consumes (removes from the front of the internal byte buffer and returns them to the caller) a byte s...">consume_buf_move()</a> directly into the packet data structure. Since <a class="el" href="classflow_1_1net__flow_1_1Node.html" title="An object of this class is a single Flow-protocol networking node, in the sense that: (1) it has a di...">Node</a> will avoid sending unless congestion window allows at least <code>N</code> bytes to be sent, in <a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#a8fe3fe5f6a33cfd8fb84eb2607fbc05b" title="Consumes (removes from the front of the internal byte buffer and returns them to the caller) a byte s...">consume_buf_move()</a> it will use <code>max_data_size == N</code>. Therefore, <a class="el" href="classflow_1_1net__flow_1_1Socket__buffer.html#a8fe3fe5f6a33cfd8fb84eb2607fbc05b" title="Consumes (removes from the front of the internal byte buffer and returns them to the caller) a byte s...">consume_buf_move()</a> will be constant-time due to performing a constant-time vector swap. Thus exactly one data copy is performed including the original <code>send()</code> call through sending bytes on the wire. </p>

<p class="definition">Definition at line <a class="el" href="socket__buffer_8hpp_source.html#l00379">379</a> of file <a class="el" href="socket__buffer_8hpp_source.html">socket_buffer.hpp</a>.</p>

<p class="reference">Referenced by <a class="el" href="socket__buffer_8cpp_source.html#l00170">clear()</a>, <a class="el" href="socket__buffer_8cpp_source.html#l00103">consume_buf_move()</a>, <a class="el" href="socket__buffer_8hpp_source.html#l00548">consume_bufs_copy()</a>, <a class="el" href="socket__buffer_8cpp_source.html#l00039">feed_buf_move()</a>, and <a class="el" href="socket__buffer_8hpp_source.html#l00395">feed_bufs_copy()</a>.</p>

</div>
</div>
<hr/>The documentation for this class was generated from the following files:<ul>
<li>net_flow/detail/<a class="el" href="socket__buffer_8hpp_source.html">socket_buffer.hpp</a></li>
<li>net_flow/detail/<a class="el" href="socket__buffer_8cpp_source.html">socket_buffer.cpp</a></li>
</ul>
</div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated on Fri Mar 28 2025 22:55:36 for Flow by&#160;<a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4
</small></address>
</body>
</html>
